﻿local Addon_name, TGJAN = ...

-- $Id: InitTourGuide.lua 230 2010-05-03 00:09:35Z eric.beaudoin $

if not TourGuide then return end

--geterrorhandler()("Loading")

-- Untility functions

local function fix_quote(text)
	text:gsub('%\%"','"')
	return text
end

--==============================================================--
--   Take the guides' |U| before GetQuestLogSpecialItemInfo     --
--      Set the HearthStone on the button for |H| tag           --
--==============================================================--

-- OK for 3.3.0.56

local dataobj = LibStub:GetLibrary("LibDataBroker-1.1"):GetDataObjectByName("TourGuide")

TourGuide.UpdateStatusFrame = nil
function TourGuide:UpdateStatusFrame()
	self:Debug(1, "UpdateStatusFrame", self.current)


	if self.updatedelay then
		local _, logi = self:GetObjectiveStatus(self.updatedelay)
		self:Debug(1, "Delayed update", self.updatedelay, logi)
		if logi then return end
	end

	local nextstep
	self.updatedelay = nil

	for i in ipairs(self.actions) do
		local turnedin, logi, complete = self:GetObjectiveStatus(i)
		if not turnedin and not nextstep then
			local action, name, quest = self:GetObjectiveInfo(i)
			local note, useitem, optional, prereq, lootitem, lootqty = self:GetObjectiveTag("N", i), self:GetObjectiveTag("U", i), self:GetObjectiveTag("O", i), self:GetObjectiveTag("PRE", i), self:GetObjectiveTag("L", i)
			self:Debug(11, "UpdateStatusFrame", i, action, name, note, logi, complete, turnedin, quest, useitem, optional, lootitem, lootqty, lootitem and GetItemCount(lootitem) or 0)
			local hasuseitem = useitem and self:FindBagSlot(useitem)
			local haslootitem = lootitem and GetItemCount(lootitem) >= lootqty
			local prereqturnedin = prereq and self.turnedin[prereq]
	
			-- Test for completed objectives and mark them done
			if action == "SETHEARTH" and self.db.char.hearth == name then return self:SetTurnedIn(i, true) end

			local zonetext, subzonetext, subzonetag = GetZoneText(), string.trim(GetSubZoneText()), self:GetObjectiveTag("SZ")
			if (action == "RUN" or action == "FLY" or action == "HEARTH" or action == "BOAT") and (subzonetext == name or subzonetext == subzonetag or zonetext == name or zonetext == subzonetag) then return self:SetTurnedIn(i, true) end

			if action == "KILL" or action == "NOTE" then
				if not optional and haslootitem then return self:SetTurnedIn(i, true) end

				local qid, quest, questtext = self:GetObjectiveTag("QID", i), self:GetObjectiveTag("Q", i), self:GetObjectiveTag("QO", i)
				if qid and questtext then
					local qi = self:GetQuestLogIndexByQID(qid)
					for lbi=1,GetNumQuestLeaderBoards(qi) do
						self:Debug(1, quest, questtext, qi, GetQuestLogLeaderBoard(lbi, qi))
						if GetQuestLogLeaderBoard(lbi, qi) == questtext then return self:SetTurnedIn(i, true) end
					end
				elseif quest and questtext then
					local qi = self:GetQuestLogIndexByName(quest)
					for lbi=1,GetNumQuestLeaderBoards(qi) do
						self:Debug(1, quest, questtext, qi, GetQuestLogLeaderBoard(lbi, qi))
						if GetQuestLogLeaderBoard(lbi, qi) == questtext then return self:SetTurnedIn(i, true) end
					end
				end
			end
			
			-- If the entry has a QID and the QID is complete, we set the entry to complete
			local qid = self:GetObjectiveTag("QID", i)
			if qid and self.turnedinquests[qid] then
				return self:SetTurnedIn(i, true)
			end
			 

			local incomplete
			if action == "ACCEPT" then incomplete = (not optional or hasuseitem or haslootitem or prereqturnedin) and not logi
			elseif action == "TURNIN" then incomplete = not optional or logi
			elseif action == "COMPLETE" then incomplete = not complete and (not optional or logi)
			elseif action == "NOTE" or action == "KILL" then incomplete = not optional or haslootitem
--			else incomplete = not logi end
			else incomplete = true end

			if incomplete then nextstep = i end

			local thisaction = action
			if nextstep and self.db.char.trackquests then
				for j=1,GetNumQuestWatches() do
					local logj = GetQuestIndexForWatch(i)
					RemoveQuestWatch(logj)
				end

				if (action == "COMPLETE" or action == "TURNIN") and logi then
					local j = i
					repeat
						action = self:GetObjectiveInfo(j)
						turnedin, logi, complete = self:GetObjectiveStatus(j)
						if action == thisaction and logi then AddQuestWatch(logi) end -- Watch quests when we can
						j = j + 1
					until action ~= thisaction
				end
			end
		end
	end
	QuestLog_Update()
	WatchFrame_Update()

	if not nextstep and self:LoadNextGuide() then return self:UpdateStatusFrame() end
	if not nextstep then return end

	self.current = nextstep
	local action, quest, fullquest = self:GetObjectiveInfo(nextstep)
	local turnedin, logi, complete = self:GetObjectiveStatus(nextstep)
	local note, useitem, optional = self:GetObjectiveTag("N", nextstep), self:GetObjectiveTag("U", nextstep), self:GetObjectiveTag("O", nextstep)

	dataobj.text, dataobj.icon = (quest or"???")..(note and " [?]" or ""), self.icons[action]
	TourGuide:CommCurrentObjective()

	self:DebugF(1, "Progressing to objective \"%s %s\"", action, quest)

	-- Mapping
	if (TomTom or Cartographer_Waypoints) and (lastmapped ~= quest or lastmappedaction ~= action) then
		lastmappedaction, lastmapped = action, quest
		self:ParseAndMapCoords(action, quest, self:GetObjectiveTag("Z", nextstep) or self.zonename, note, self:GetObjectiveTag("QID", nextstep))
	end

	if self.db.char.showuseitem and action == "COMPLETE" and self.db.char.showuseitemcomplete then
		local useitem2 = GetQuestLogSpecialItemInfo(logi or 0)
		if useitem2 then useitem2 = tonumber(useitem2:match("item:(%d+):")) end
		self:SetUseItem(useitem or useitem2)
	elseif self.db.char.showuseitem and action ~= "COMPLETE" then
		self:SetUseItem(useitem)
	elseif action == "HEARTH" then
		-- Set the Hearthstone for an easier hearth
		self:SetUseItem("6948")
	else
		self:SetUseItem()
	end

	self:UpdateOHPanel()
	self:UpdateGuidesPanel()
end


--==========================================================--
--            Display the tooltip on the use button         --
--==========================================================--

-- OK for 3.3.0.56
do

	local frame = _G["TourGuideItemFrame"]
	local item

	frame:HookScript("OnEnter", function (self) --item:16846:0:0:0:0:0:0:0
		if item then
			GameTooltip:SetOwner(self); GameTooltip:SetHyperlink("item:"..item); GameTooltip:Show();
		end
	end);
	frame:HookScript("OnLeave", GameTooltip_Hide);

	local old_SetUseItem = TourGuide.SetUseItem
	
	local function SetUseItem(self, use, tex)
		item = use
		return old_SetUseItem(self, use, tex)
	end
	TourGuide.SetUseItem = SetUseItem

end


--==========================================================--
--     Map from notes instead of LightHeaded if present     --
--        Refresh maped POI on each quest log update        --
--==========================================================--

-- OK for 3.3.0.56

do

	local L = TourGuide.Locale

	local zonei, zonec, zonenames = {}, {}, {}
	for ci,c in pairs{GetMapContinents()} do
		zonenames[ci] = {GetMapZones(ci)}
		for zi,z in pairs(zonenames[ci]) do
			zonei[z], zonec[z] = zi, ci
		end
	end


	local cache = {}
	local function MapPoint(zone, x, y, desc, c, z)
		TourGuide:DebugF(1, "Mapping %q - %s (%.2f, %.2f)", desc, zone or z, x, y)
		local zi, zc = z or zone and zonei[zone], c or zone and zonec[zone]
		if not zi then
			if zone then TourGuide:PrintF(L["Cannot find zone %q, using current zone."], zone)
			else TourGuide:Print(L["No zone provided, using current zone."]) end

			zi, zc = GetCurrentMapZone(), GetCurrentMapContinent()
		end
		if zc == -1 then return end -- Cosmic zone cannot be mapped by TomTom
		zone = zone or zonenames[zc][zi]

		if TomTom then 
			local wpid = TomTom:AddZWaypoint(zc, zi, x, y, desc, false)
			table.insert(cache, wpid)
			return wpid
		elseif Cartographer_Waypoints then
			local pt = NotePoint:new(zone, x/100, y/100, desc)
			Cartographer_Waypoints:AddWaypoint(pt)
			table.insert(cache, pt.WaypointID)
			return pt.WaypointID
		end
	end

	local tries = 0
	local elapsed = 0
	local taction, tquest, tzone, tnote, tqid, tlogi
	local f = CreateFrame("Frame")
	f:Hide()
	f:SetScript("OnShow", 
					function() 
--geterrorhandler()(format("Show: %d", elapsed))
						elapsed = 0; tries = 0
	end)
	f:SetScript("OnUpdate", function(self, elap)
		elapsed = elapsed + elap
		if elapsed < .2 then return end
		tries = tries + 1
		elapsed = 0
		if tries <= 10 then
			if TourGuide:MapPOI(taction,tqid) then
				self:Hide()
			end
		else
			-- We didn't find it so we need to go to plan B
			self:Hide()
			TourGuide:ParseAndMapCoords2(taction, tquest, tzone, tnote, tqid, tlogi)
		end
	end)

	assert(not TourGuide.ResetMapCoords, "TourGuide:ResetMapCoords() already exists")
	function TourGuide:ResetMapCoords(with_nopoi)
		self:ParseAndMapCoords(taction, tquest, tzone, tnote, tqid, tlogi,with_nopoi)
	end

	local temp = {}
	TourGuide.ParseAndMapCoords = nil
	function TourGuide:ParseAndMapCoords(action, quest, zone, note, qid, logi, with_nopoi)
		-- We keep the values in case we have to call /poi to reset the arrow
		taction, tquest, tzone, tnote, tqid, tlogi = action, quest, zone, note, qid, logi
--geterrorhandler()(format("Parse: action = %s, qid = %d",action or 'nil',qid or -1))
		if TomTom and TomTom.RemoveWaypoint then
			while cache[1] do TomTom:RemoveWaypoint(table.remove(cache)) end
		elseif Cartographer_Waypoints then
			while cache[1] do Cartographer_Waypoints:CancelWaypoint(table.remove(cache)) end
		end
		self:RemovePOI()

		local questtext = self:GetObjectiveTag("QO")
		local nopoi = (with_nopoi == nil and self:GetObjectiveTag("NOPOI")) or with_nopoi
		if (not nopoi and qid and (action == "COMPLETE" or action == "TURNIN" or questtext)) then
			if not self:MapPOI(action,qid) then
				--taction, tquest, tzone, tnote, tqid, tlogi = action, quest, zone, note, qid, logi
				f:Show() 
			end
			return
		end
		
		-- Blizard POI is not used
		TourGuide:ParseAndMapCoords2(action, quest, zone, note, qid, logi)
	end
	
	assert(not TourGuide.ParseAndMapCoords2, "TourGuide:ParseAndMapCoords2() already exists")
	function TourGuide:ParseAndMapCoords2(action, quest, zone, note, qid, logi)
		note = note or ''
		if self.db.char.mapnotecoords then 
			for x,y in note:gmatch(L.COORD_MATCH) do table.insert(temp, tonumber(y)); table.insert(temp, tonumber(x)); found = true end
		end
		if (action == "ACCEPT" or action == "TURNIN") and #temp == 0 then self:MapLightHeadedNPC(qid, action, quest) end
		while temp[1] do MapPoint(zone, table.remove(temp), table.remove(temp), "[TG] "..quest) end
	end

	TourGuide.MapLightHeadedNPC = nil
	function TourGuide:MapLightHeadedNPC(qid, action, quest)
		if not self.db.char.mapquestgivers then return end

		local npcid, npcname, stype
		if action == "ACCEPT" then _, _, _, _, stype, npcname, npcid = LightHeaded:GetQuestInfo(qid)
		else _, _, _, _, _, _, _, stype, npcname, npcid = LightHeaded:GetQuestInfo(qid) end
		self:Debug(1, "LightHeaded lookup", action, qid, stype, npcname, npcid)
		if stype ~= "npc" then return end

		local data = LightHeaded:LoadNPCData(tonumber(npcid))
		if not data then return end
		for zid,x,y in data:gmatch("([^,]+),([^,]+),([^:]+):") do MapPoint(nil, tonumber(x), tonumber(y), "[LH] "..quest.." ("..fix_quote(npcname)..")", LightHeaded:WZIDToCZ(tonumber(zid))) end
		return true
	end

--[[ Not needed
	-- Add |NOPOI| to TourGuide
	TourGuide.GetObjectiveTag = nil
	function TourGuide:GetObjectiveTag(tag, i)
		self:Debug(11, "GetObjectiveTag", tag, i)
		i = i or self.current
		local tags = self.tags[i]
		if not tags then return end
	
		if tag == "O" then return tags:find("|O|")
		elseif tag == "T" then return tags:find("|T|")
		elseif tag == "NOPOI" then return tags:find("|NOPOI|")
		elseif tag == "QID" then return tonumber((tags:match("|QID|(%d+)|")))
		elseif tag == "L" then
			local _, _, lootitem, lootqty = tags:find("|L|(%d+)%s?(%d*)|")
			lootqty = tonumber(lootqty) or 1
	
			return lootitem, lootqty
		end
	
		return select(3, tags:find("|"..tag.."|([^|]*)|?"))
	end
]]--

	-- KILL and NOTE lines accept QID
   -- refresh the POI arrow with every log update
	TourGuide.QUEST_LOG_UPDATE = nil
	function TourGuide:QUEST_LOG_UPDATE(event)
--geterrorhandler()(format("Event: %s",event))
		self:QuestID_QUEST_LOG_UPDATE()

		local action, _, logi, complete = self:GetObjectiveInfo(), self:GetObjectiveStatus()
		self:Debug(10, "QUEST_LOG_UPDATE", action, logi, complete)

		if (self.updatedelay and not logi) or action == "ACCEPT" or action == "COMPLETE" and complete then self:UpdateStatusFrame() end

		if action == "KILL" or action == "NOTE" then
			if complete then self:UpdateStatusFrame() end
			--if self:GetObjectiveTag("QID") then return end

			local qid, quest, questtext = self:GetObjectiveTag("QID"), self:GetObjectiveTag("Q"), self:GetObjectiveTag("QO")
			
			if qid and questtext then
				local qi = self:GetQuestLogIndexByQID(qid)
				for lbi=1,GetNumQuestLeaderBoards(qi) do
					if GetQuestLogLeaderBoard(lbi, qi) == questtext then return self:SetTurnedIn(i, true) end
				end
			elseif quest and questtext then 
				local qi = self:GetQuestLogIndexByName(quest)
				for i=1,GetNumQuestLeaderBoards(qi) do
					if GetQuestLogLeaderBoard(i, qi) == questtext then self:SetTurnedIn() end
				end
			end
		end
		
		self:MapPOI(action)
	end

--geterrorhandler()("Loading MapPOI")

	-- New functions

	local currentPOI, currentQID, currentX, currentY = nil, nil, nil, nil
	
	assert(not TourGuide.RemovePOI, "TourGuide:RemovePOI() already exists")
	function TourGuide:RemovePOI()
		if currentPOI then
			if TomTom and TomTom.RemoveWaypoint then
				TomTom:RemoveWaypoint(currentPOI)
			elseif Cartographer_Waypoints then
				Cartographer_Waypoints:CancelWaypoint(currentPOI) 
			end
		end
		currentPOI, currentQID, currentX, currentY = nil, nil, nil, nil
	end
	
	assert(not TourGuide.MapPOI, "TourGuide:MapPOI() already exists")
	function TourGuide:MapPOI(action,qid) 
		action = action or self.actions[self.current]
		
		if action ~= "COMPLETE" and action ~= "TURNIN" and not self:GetObjectiveTag("QO") then 
			self:RemovePOI()
			return false 
		end
		
		local qid = qid or self:GetObjectiveTag("QID")
		local nopoi = self:GetObjectiveTag("NOPOI")
--geterrorhandler()(format("MapPOI: action = %s, qid = %d",action or 'nil',qid or -1))
		
		if not nopoi and qid then
			QuestMapUpdateAllQuests()
			QuestPOIUpdateIcons()
			local _, x, y, obj = QuestPOIGetIconInfo(qid)
			if x and y then
				--local zone = self:GetObjectiveTag("Z") or self.zonename
				-- If there is a value, it's in the curent zone
				local zone = GetRealZoneText()
				local questTitle, questID, i = '', nil, 1
				while questID ~= qid and i <= GetNumQuestLogEntries() do
					questTitle, _, _, _, _, _, _, _, questID = GetQuestLogTitle(i)
					i = i + 1
				end
				if questID == qid then
--geterrorhandler()(format("MapPOI: currentPOI = %s, currentQID = %d",currentPOI or 'nil',currentQID or -1))
					if not (currentPOI and currentQID == qid and currentX == x and currentY == y) then
						local npc = ''
						if action == "TURNIN" and LightHeaded and LightHeaded.GetQuestInfo then
							npc = select(9,LightHeaded:GetQuestInfo(qid))
							if npc then 
								npc = " ("..fix_quote(npc)..")" 
							--else
							--	npc = ''
							--	geterrorhandler()(format("No NPC: action = %s, qid = %d",action or 'nil',qid or -1))
							end
						end
					
						self:RemovePOI()
						currentPOI = MapPoint(zone, x*100, y*100, "[POI] "..questTitle..(npc or ''))
						currentQID, currentX, currentY = qid, x, y
					end
					return true
				else
					self:RemovePOI()
					return false
				end
			else
				return false
			end
		end
		
		self:RemovePOI()
		return false
	end

end


--==============================================================--
--     Use GetQuestsCompleted to refresh the guides' quests     --
--     				Save turnedinquests ourselves						 --
--==============================================================--

-- OK for 3.3.0.56
do
--geterrorhandler()("Called InitTourGuide.lua")

	-- New function
	local currentquests, oldquests, titles, firstscan, abandoning = {}, {}, {}, true
	TourGuide.turnedinquests = TourGuide.turnedinquests or {}
	TourGuide.completedquests = {}
	--TGJAN_completedquests = completedquests
	
	TourGuide.QUEST_QUERY_COMPLETE = nil
	function TourGuide:QUEST_QUERY_COMPLETE()
		GetQuestsCompleted(self.completedquests)
		-- Set the completed quests as completed for TourGuide
		for qid in pairs(self.completedquests) do self.turnedinquests[qid] = true end 
		self:UpdateStatusFrame()
	end
	
	-- We need to catch Touguide:Enable()
	TourGuide.Enable = nil
	function TourGuide:Enable()
--geterrorhandler()("Called TourGuide:Enable()")
		self.Enable = nil -- Dongle likes to call Enable multiple times if we bug LightHeaded... so we need to nil out to ensure we are only called once
		if TomTom and TomTom.version ~= "SVN" and (tonumber(TomTom.version) or 0) < 120 then self:Print("Your version of TomTom is out of date.  TourGuide waypoints may not work correctly.") end
	
		-- Set the starting guides to WoW-Pro versions
		if self.db.char.currentguide == "No Guide" and UnitLevel("player") == 1 and UnitXP("player") == 0 then
			local startguides = {BloodElf = "[WoW-Pro|Snowflake] Eversong Woods (1-12)", 
										Orc = "[WoW-Pro|Zerinj] Durotar (1-12)", 
										Troll = "[WoW-Pro|Zerinj] Durotar (1-12)", 
										Tauren = "[WoW-Pro|Shinke] Mulgore (1-12)", 
										Undead = "[WoW-Pro|Manovan] Tirisfal Glades (1-12)",
										Dwarf = "[WoW-Pro|Boston] Dun Morogh (1-12)", 
										Gnome = "[WoW-Pro|Boston] Dun Morogh (1-12)", 
										Dreanei = "[WoW-Pro|Snowflake] Azuremyst Isle (1-12)", 
										Human = "[WoW-Pro|Maw] Elwynn Forest (1-12)", 
										NightElf = "[WoW-Pro|Taralom] Teldrassil (1-12)"}
			self.db.char.currentguide = startguides[select(2, UnitRace("player"))] or self.guidelist[1]
		end
	
		self.db.char.currentguide = self.db.char.currentguide or self.guidelist[1]
		if self.guides[self.db.char.currentguide] then
			self:LoadGuide(self.db.char.currentguide)
		else
			local guidenotloaded = self.db.char.currentguide
	
			function self:Disable(...)
				if not self.db.char.currentguide then self.db.char.currentguide = guidenotloaded end
			end
	
			function self:ADDON_LOADED()
				if not self.guides[guidenotloaded] then return end
				self:LoadGuide(guidenotloaded)
				self:UpdateStatusFrame()
				self:UpdateGuidesPanel()
				self:UnregisterEvent("ADDON_LOADED")
				self.ADDON_LOADED = nil
				self.Disable = orig
			end
			self:RegisterEvent("ADDON_LOADED")
	
			self:LoadGuide(self.guidelist[1])
		end
		self:PositionStatusFrame()
		self:PositionItemFrame()
	
		self.TrackEvents = self.TrackEvents or {}
		for _,event in pairs(self.TrackEvents) do self:RegisterEvent(event) end
		self:RegisterEvent("QUEST_COMPLETE", "UpdateStatusFrame")
		self:RegisterEvent("QUEST_DETAIL", "UpdateStatusFrame")
		self:RegisterEvent("PARTY_MEMBERS_CHANGED", "CommCurrentObjective")
		self.TrackEvents = nil
		self:QuestID_QUEST_LOG_UPDATE()
		--GetQuestsCompleted(TourGuide.turnedinquests)
		--self:UpdateStatusFrame()
		self:QUEST_QUERY_COMPLETE()
		self:RegisterEvent("QUEST_QUERY_COMPLETE")
		if IsLoggedIn() then QueryQuestsCompleted()
		else
			self:RegisterEvent("PLAYER_LOGIN")
			function self:PLAYER_LOGIN()
				QueryQuestsCompleted()
				self:UnregisterEvent("PLAYER_LOGIN")
				self.PLAYER_LOGIN = nil
			end
		end
	end

	
	-- Make sure that our enable stuff is called after TourGuide:Enable() is called at least once
	local frame = CreateFrame("frame")
	frame:SetScript("OnEvent", function(self, event, ...) if self[event] then return self[event](self, event, ...) end end)
	frame:RegisterEvent("ADDON_LOADED")
	
	function frame:ADDON_LOADED(event, addon)
--geterrorhandler()("Called frame:ADDON_LOADED()")
		if addon ~= Addon_name then return end

		self:UnregisterEvent("ADDON_LOADED")
		self.ADDON_LOADED = nil
	
		if IsLoggedIn() then self:PLAYER_LOGIN() else self:RegisterEvent("PLAYER_LOGIN") end
	end

	function frame:PLAYER_LOGIN()
--geterrorhandler()("Called frame:PLAYER_LOGIN()")
		-- Validate TourGuide version
		local TourGuide_version = GetAddOnMetadata("TourGuide", "Version")
		if not TourGuide_version or TourGuide_version ~= "3.3.0.56" then
			geterrorhandler()("Warning: TourGuide_Jame has only been tested with TourGuide version 3.3.0.56. You may have issues if you use other TourGuide versions. Version detected: " .. (TourGuide_version or 'nil'))
		end

		--self:RegisterEvent("PLAYER_LOGOUT")
		-- Make sure that TourGuide.Enable is called before our stuff
		if TourGuide.Enable then TourGuide:Enable() end

		TourGuide:QuestID_QUEST_LOG_UPDATE()		
		--TourGuide:QUEST_QUERY_COMPLETE()
		--TourGuide:RegisterEvent("QUEST_QUERY_COMPLETE")
		--QueryQuestsCompleted()

		self:RegisterEvent("PLAYER_LOGOUT")

		self:UnregisterEvent("PLAYER_LOGIN")
		self.PLAYER_LOGIN = nil
	end
	
	function frame:PLAYER_LOGOUT()
	--geterrorhandler()("Called frame:PLAYER_LOGOUT()")
		TGJANQuestHistoryDB = {}
		for qid,v in pairs(TourGuide.turnedinquests) do 
			if v then 
				tinsert(TGJANQuestHistoryDB,qid)
			end 
		end
	end

	TourGuide.QuestID_QUEST_LOG_UPDATE = nil
	function TourGuide:QuestID_QUEST_LOG_UPDATE()
		local qids = self.QIDmemo
	
		currentquests, oldquests = oldquests, currentquests
		for i in pairs(currentquests) do currentquests[i] = nil end

		for i=1,GetNumQuestLogEntries() do
			local link = GetQuestLink(i)
			local qid = link and qids[link]
			if qid then
				currentquests[qid] = true
				titles[qid] = GetQuestLogTitle(i)
			end
		end

		if firstscan then
			--geterrorhandler()("firstscan")
	
			--TGJANQuestHistoryDB = TGJANQuestHistoryDB or {}
			if not TGJANQuestHistoryDB or type(TGJANQuestHistoryDB) == 'string' then
				TGJANQuestHistoryDB = {}
			end
			-- Clean the variable if it was set from TourGuide save variable
			for qid in pairs(self.turnedinquests) do
				self.turnedinquests[qid] = nil
			end
			for i,qid in ipairs(TGJANQuestHistoryDB) do
				self.turnedinquests[qid] = true
			end
			firstscan = nil
			TGJANQuestHistoryDB = nil
			return
		end

		for qid in pairs(oldquests) do
			if not currentquests[qid] then
				local action = abandoning and "Abandoned quest" or "Turned in quest"
				if not abandoning then self.turnedinquests[qid] = true end
				abandoning = nil
				self:Debug(1, action, qid, titles[qid])
				return self:UpdateStatusFrame()
			end
		end

		for qid in pairs(currentquests) do
			if not oldquests[qid] then
				self:Debug(1, "Accepted quest", qid, titles[qid])
				return self:UpdateStatusFrame()
			end
		end
	end

	-- No longer needed
--[[	
	TourGuide.Disable = nil
	function TourGuide:Disable()
	--geterrorhandler()("Called TourGuide:Disable()")
	-- Do nothing
	end
]]--

	local function MyAbandonQuest(...)
		abandoning = true
	end
	hooksecurefunc("AbandonQuest", MyAbandonQuest)

--[[ might not be needed for 3.3.0.56
	-- If we Shift-Click a guide, we reset the completed quest
	local frame = TourGuide.guidespanel
	local L = TourGuide.Locale
	local NUMROWS, ROWHEIGHT, GAP, EDGEGAP = 18, 17, 8, 16
	local offset, rows = 0, {}
	
	frame:SetScript("OnShow", function()
		local title, subtitle = LibStub("tekKonfig-Heading").new(frame, L["Tour Guide - Guides"], L["This panel lets you choose a guide to load.  Upon completion the next guide will load automatically.  Completed guides can be reset by shift-clicking."])
	
		local group = LibStub("tekKonfig-Group").new(frame, nil, "TOP", subtitle, "BOTTOM", 0, -EDGEGAP-GAP)
		group:SetPoint("LEFT", EDGEGAP, 0)
		group:SetPoint("BOTTOMRIGHT", -EDGEGAP, EDGEGAP)
	
		local scrollbar = LibStub("tekKonfig-Scroll").new(group, 6, NUMROWS/3)
	
		local function OnClick(self)
			if IsShiftKeyDown() then
				TourGuide.db.char.completion[self.guide] = nil
				TourGuide.db.char.turnins[self.guide] = {}
				for qid in string.gmatch(TourGuide.guides[self.guide](), "|QID|(%d+)|") do TourGuide.turnedinquests[tonumber(qid)] = TourGuide.completedquests[tonumber(qid)] end
				TourGuide:UpdateStatusFrame()
				TourGuide:UpdateGuidesPanel()
				GameTooltip:Hide()
				QueryQuestsCompleted()
			else
				local text = self.guide
				if not text then self:SetChecked(false)
				else
					TourGuide:LoadGuide(text)
					TourGuide:UpdateStatusFrame()
					TourGuide:UpdateGuidesPanel()
				end
			end
		end
		rows = {}
		for i=1,NUMROWS do
			local row = CreateFrame("CheckButton", nil, group)
			if i == 1 then row:SetPoint("TOP", 0, -4)
			else row:SetPoint("TOP", rows[i-1], "BOTTOM") end
			row:SetPoint("LEFT", 4, 0)
			row:SetPoint("RIGHT", scrollbar, "LEFT", -4, 0)
			row:SetHeight(ROWHEIGHT)
	
			local highlight = row:CreateTexture()
			highlight:SetTexture("Interface\\HelpFrame\\HelpFrameButton-Highlight")
			highlight:SetTexCoord(0, 1, 0, 0.578125)
			highlight:SetAllPoints()
			row:SetHighlightTexture(highlight)
			row:SetCheckedTexture(highlight)
	
			local text = row:CreateFontString(nil, nil, "GameFontWhite")
			text:SetPoint("LEFT", GAP, 0)
			local complete = row:CreateFontString(nil, nil, "GameFontWhite")
			complete:SetPoint("RIGHT", -GAP, 0)
	
			row:SetScript("OnClick", OnClick)
	
			row.text = text
			row.complete = complete
			rows[i] = row
		end
	
	
		local f = scrollbar:GetScript("OnValueChanged")
		scrollbar:SetMinMaxValues(0, math.max(0, #TourGuide.guidelist - NUMROWS - 1))
		scrollbar:SetScript("OnValueChanged", function(self, value, ...)
			offset = math.floor(value)
			TourGuide:UpdateGuidesPanel()
			return f(self, value, ...)
		end)
	
		frame:EnableMouseWheel()
		frame:SetScript("OnMouseWheel", function(self, val) scrollbar:SetValue(scrollbar:GetValue() - val*NUMROWS/3) end)
	
		local function newoffset() for i,name in ipairs(TourGuide.guidelist) do if name == TourGuide.db.char.currentguide then return i - (NUMROWS/2) - 1 end end end
		local function OnShow(self) scrollbar:SetValue(newoffset() or 0) end
		frame:SetScript("OnShow", OnShow)
		OnShow(frame)
	end)
]]--

--[[ might not be needed for 3.3.0.56
	TourGuide.UpdateGuidesPanel = nil
	function TourGuide:UpdateGuidesPanel()
		if not frame:IsVisible() then return end
		for i,row in ipairs(rows) do
			row.i = i + offset + 1

			local name = self.guidelist[i + offset + 1]
			row.text:SetText(name)
			row.guide = name
			row:SetChecked(self.db.char.currentguide == name)

			local complete = self.db.char.currentguide == name and (self.current-1)/#self.actions or self.db.char.completion[name]
			local r,g,b = self.ColorGradient(complete or 0)
			local completetext = complete and complete ~= 0 and string.format(L["|cff%02x%02x%02x%d%% complete"], r*255, g*255, b*255, complete*100)
			row.complete:SetText(completetext)
		end
	end
]]--
end

--==============================================================--
--   QID should be used only for Accept, Complete and Turnin    --
--   when manualy checking a guide step.								 --
--   If other type of entries have a |QID|, burn it only if in  --
--   the complete quests list.											 --
--   In other words, in A, C or T line, all the lines with the  --
--   same QID will be checked. If in other lines, only the      --
--   curent line will be checked. Also, it is not permitted to	 --
--   uncheck a line is a QID for a quest that Blizzard says is  --
--   completed.                                                 --
--==============================================================--

-- OK for 3.3.0.56

TourGuide.SetTurnedIn = nil
function TourGuide:SetTurnedIn(i, value, noupdate)
	if not i then
		i = self.current
		value = true
	end
--geterrorhandler()(format("SetTurnedIn: i=%d, value = %s, noupdate = %s",i or -1, value or 'nil',noupdate or 'nil'))

	if value then value = true else value = nil end -- Cleanup to minimize savedvar data

	local qid = self:GetObjectiveTag("QID", i)
	local action = self.actions[i]

--	if qid and (action == "ACCEPT" or action == "COMPLETE" or action == "TURNIN") then 
	if qid and action == "TURNIN" then 
		self.turnedinquests[qid] = value or self.completedquests[qid]
	end
	if qid and self.turnedinquests[qid] then
		self.turnedin[self.quests[i]] = true
	else
		self.turnedin[self.quests[i]] = value
	end
	self:DebugF(1, "Set turned in %q = %s", self.quests[i], tostring(value))
	if not noupdate then self:UpdateStatusFrame()
	else self.updatedelay = i end
end

--==============================================================--
--   Allow more flexibility for the (Part %d) info in quests    --
--==============================================================--

-- OK for 3.3.0.56

if TourGuide.Locale and TourGuide.Locale.PART_GSUB then
	TourGuide.Locale.PART_GSUB = "%s%([Pp]art %d+%)"
end

if TourGuide.Locale and TourGuide.Locale.PART_FIND then
	TourGuide.Locale.PART_FIND = "(.+)%s%([Pp]art %d+%)"
end

--==============================================================--
--         Allow QID to work with every type of action          --
--==============================================================--

-- Might not bee needed with 3.3.0.56
while false do

local L = TourGuide.Locale
local ww = WidgetWarlock


local ROWHEIGHT = 30
local ROWOFFSET = 6
local NUMROWS = math.floor(305/ROWHEIGHT)


local offset = 0
local rows = {}
TourGuide.rows = rows
local scrollbar, upbutt, downbutt, title, completed


local frame = TourGuide.objectiveframe

local function OnShow(self)
	local newval = math.max(0, (TourGuide.current or 0) - NUMROWS/2 - 1)

	scrollbar:SetMinMaxValues(0, math.max(#TourGuide.actions - NUMROWS, 1))
	scrollbar:SetValue(newval)

	TourGuide:UpdateOHPanel()

	self:SetAlpha(0)
	self:SetScript("OnUpdate", ww.FadeIn)
end


local function HideTooltip() GameTooltip:Hide() end

local function ShowTooltip(f)
	if f.text:GetStringWidth() <= f:GetWidth() then return end

	GameTooltip:SetOwner(f, "ANCHOR_RIGHT")
	GameTooltip:SetText(f.text:GetText(), nil, nil, nil, nil, true)
end


local function ShowTooltip2(f)
	if not f.qid then return end

	GameTooltip:SetOwner(f, "ANCHOR_RIGHT")
	GameTooltip:SetHyperlink("quest:"..f.qid)
end


local function CreateButton(parent, ...)
	local b = CreateFrame("Button", nil, parent)
	if select("#", ...) > 0 then b:SetPoint(...) end
	b:SetWidth(120) b:SetHeight(22)

	-- Fonts --
	b:SetDisabledFontObject(GameFontDisable)
	b:SetHighlightFontObject(GameFontHighlight)
	b:SetNormalFontObject(GameFontNormal)

	-- Textures --
	b:SetNormalTexture("Interface\\Buttons\\UI-Panel-Button-Up")
	b:SetPushedTexture("Interface\\Buttons\\UI-Panel-Button-Down")
	b:SetHighlightTexture("Interface\\Buttons\\UI-Panel-Button-Highlight")
	b:SetDisabledTexture("Interface\\Buttons\\UI-Panel-Button-Disabled")
	b:GetNormalTexture():SetTexCoord(0, 0.625, 0, 0.6875)
	b:GetPushedTexture():SetTexCoord(0, 0.625, 0, 0.6875)
	b:GetHighlightTexture():SetTexCoord(0, 0.625, 0, 0.6875)
	b:GetDisabledTexture():SetTexCoord(0, 0.625, 0, 0.6875)
	b:GetHighlightTexture():SetBlendMode("ADD")

	return b
end

TourGuide.CreateObjectivePanel = nil
function TourGuide:CreateObjectivePanel()
	local guidebutton = CreateButton(frame, "BOTTOMRIGHT", -6, 6)
	guidebutton:SetText(L["Guides"])
	guidebutton:SetScript("OnClick", function() HideUIPanel(frame); InterfaceOptionsFrame_OpenToCategory(TourGuide.guidespanel) end)

	local configbutton = CreateButton(frame, "RIGHT", guidebutton, "LEFT")
	configbutton:SetText(L["Config"])
	configbutton:SetScript("OnClick", function() HideUIPanel(frame); InterfaceOptionsFrame_OpenToCategory(TourGuide.configpanel) end)

	if tekDebug then
		local b = CreateButton(frame, "RIGHT", configbutton, "LEFT")
		b:SetText("Debug")
		b:SetScript("OnClick", function() frame:Hide(); LibStub("OptionHouse-1.1"):Open("tekDebug", "TourGuide") end)
	end

	title = ww.SummonFontString(frame, nil, "SubZoneTextFont", nil, "BOTTOM", frame, "TOP")
	local fontname, fontheight, fontflags = title:GetFont()
	title:SetFont(fontname, 18, fontflags)

	completed = ww.SummonFontString(frame, nil, "NumberFontNormalLarge", nil, "BOTTOMLEFT", 10, 10)

	scrollbar, upbutt, downbutt = ww.ConjureScrollBar(frame)
	scrollbar:SetPoint("TOPRIGHT", frame, -7, -21)
	scrollbar:SetPoint("BOTTOM", frame, 0, 22+22)
	scrollbar:SetScript("OnValueChanged", function(f, val) self:UpdateOHPanel(val) end)

	upbutt:SetScript("OnClick", function(f)
		scrollbar:SetValue(offset - NUMROWS + 1)
		PlaySound("UChatScrollButton")
	end)

	downbutt:SetScript("OnClick", function(f)
		scrollbar:SetValue(offset + NUMROWS - 1)
		PlaySound("UChatScrollButton")
	end)

	local bg = {bgFile = "Interface/Tooltips/UI-Tooltip-Background"}
	for i=1,NUMROWS do
		local row = CreateFrame("Button", nil, frame)
		row:SetPoint("TOPLEFT", i == 1 and frame or rows[i-1], i == 1 and "TOPLEFT" or "BOTTOMLEFT", 0, i == 1 and -3 or 0)
		row:SetWidth(630-24)
		row:SetHeight(ROWHEIGHT)
		row:SetBackdrop(bg)

		local check = ww.SummonCheckBox(ROWHEIGHT-ROWOFFSET, row, "LEFT", ROWOFFSET, 0)
		local icon = ww.SummonTexture(row, nil, ROWHEIGHT-ROWOFFSET, ROWHEIGHT-ROWOFFSET, nil, "LEFT", check, "RIGHT", ROWOFFSET, 0)
		local text = ww.SummonFontString(row, nil, "GameFontNormal", nil, "LEFT", icon, "RIGHT", ROWOFFSET, 0)

		local questhover = CreateFrame("Button", nil, row)
		questhover:SetAllPoints(text)
		questhover:SetScript("OnEnter", ShowTooltip2)
		questhover:SetScript("OnLeave", HideTooltip)

		local detailhover = CreateFrame("Button", nil, row)
		detailhover:SetHeight(ROWHEIGHT-ROWOFFSET)
		detailhover:SetPoint("LEFT", text, "RIGHT", ROWOFFSET*3, 0)
		detailhover:SetPoint("RIGHT", scrollbar, "LEFT", -ROWOFFSET, 0)
		detailhover:SetScript("OnEnter", ShowTooltip)
		detailhover:SetScript("OnLeave", HideTooltip)

		local detail = ww.SummonFontString(detailhover, nil, "GameFontNormal", nil)
		detail:SetAllPoints(detailhover)
		detail:SetJustifyH("RIGHT")
		detail:SetTextColor(240/255, 121/255, 2/255)
		detailhover.text = detail

		check:SetScript("OnClick", function(f) self:SetTurnedIn(row.i, f:GetChecked()) end)

		row.text = text
		row.questhover = questhover
		row.detail = detail
		row.check = check
		row.icon = icon
		rows[i] = row
	end

	frame:EnableMouseWheel()
	frame:SetScript("OnMouseWheel", function(f, val)
		scrollbar:SetValue(offset - val)
	end)

	frame:SetScript("OnShow", OnShow)
	ww.SetFadeTime(frame, 0.5)
	OnShow(frame)
	return frame
end


-- Only this function was really modified.
--local accepted = {}
--TourGuide.accepted = accepted
TourGuide.UpdateOHPanel = nil
function TourGuide:UpdateOHPanel(value)

	if not frame or not frame:IsVisible() then return end

	title:SetText(self.db.char.currentguide or L["No Guide Loaded"])
	local r,g,b = self.ColorGradient((self.current-1)/#self.actions)
	completed:SetText(string.format(L["|cff%02x%02x%02x%d%% complete"], r*255, g*255, b*255, (self.current-1)/#self.actions*100))

	self.guidechanged = nil
	if value then offset = math.floor(value) end
	if (offset + NUMROWS) > #self.actions then offset = #self.actions - NUMROWS end
	if offset < 0 then offset = 0 end

	if offset == 0 then upbutt:Disable() else upbutt:Enable() end
	if offset == (#self.actions - NUMROWS) then downbutt:Disable() else downbutt:Enable() end

	--for i in pairs(accepted) do accepted[i] = nil end

	--[[
	for i in pairs(self.actions) do
		local action, name = self:GetObjectiveInfo(i)
		local _, _, quest, part = name:find(L.PART_FIND)
		if quest and not accepted[quest] and not self:GetObjectiveStatus(i) then accepted[quest] = name end
	end
	]]--

	for i,row in ipairs(rows) do
		row.i = i + offset
		local action, name = self:GetObjectiveInfo(i + offset)
		if not name then row:Hide()
		else
			local turnedin, logi, complete = self:GetObjectiveStatus(i + offset)
			local optional, intown = self:GetObjectiveTag("O", i + offset), self:GetObjectiveTag("T", i + offset)
			row:Show()

			if intown then row:SetBackdropColor(0,0.5,0,0.5) else row:SetBackdropColor(0,0,0,0) end

			local shortname = name:gsub(L.PART_GSUB, "")
--			logi = not turnedin and (not accepted[shortname] or (accepted[shortname] == name)) and logi
			logi = not turnedin and logi
--			complete = not turnedin and (not accepted[shortname] or (accepted[shortname] == name)) and complete
			complete = not turnedin and complete
			local checked = turnedin or action == "ACCEPT" and logi or action == "COMPLETE" and complete

			row.icon:SetTexture(self.icons[action])
			if action ~= "ACCEPT" and action ~= "TURNIN" then row.icon:SetTexCoord(4/48, 44/48, 4/48, 44/48) end
			row.text:SetText(name..(optional and L[" |cff808080(Optional)"] or ""))
			row.detail:SetText(self:GetObjectiveTag("N", i + offset))
			row.check:SetChecked(checked)
			row.questhover.qid = self:GetObjectiveTag("QID", i + offset)

			if (TourGuide.current > (i + offset)) and optional and not checked then
				row.text:SetTextColor(0.5, 0.5, 0.5)
--~ 				row.check:SetChecked(true)
				row.check:Disable()
			else
				row.text:SetTextColor(1, 0.82, 0)
				row.check:Enable()
			end

			if self.db.char.currentguide == "No Guide" then row.check:Disable() end
		end
	end
end

end

-- OK for 3.3.0.56
-- Staying, there is no reason to need the name of a quest to find
-- the quest log id

TourGuide.GetQuestDetails = nil
function TourGuide:GetQuestDetails(name, qid)
	--if not name then return end

--	local i = qid and self:GetQuestLogIndexByQID(qid) or self:GetQuestLogIndexByName(name)
	local i = qid and self:GetQuestLogIndexByQID(qid)
	local complete = i and select(7, GetQuestLogTitle(i)) == 1
	return i, complete
end

--==============================================================--
--   Fix for single turn in i.e. quests that are accepted and   --
--   turnin at the same time.												 --
--==============================================================--

-- OK for 3.3.0.56

TourGuide.CHAT_MSG_SYSTEM = nil
function TourGuide:CHAT_MSG_SYSTEM(event, msg)
	local L = TourGuide.Locale
	local action, quest = self:GetObjectiveInfo()

	local _, _, loc = msg:find(L["(.*) is now your home."])
	if loc then
		self:DebugF(1, "Detected setting hearth to %q", loc)
		self.db.char.hearth = loc
		return action == "SETHEARTH" and loc == quest and self:SetTurnedIn()
	end

	if action == "ACCEPT" then
		local _, _, text = msg:find(L["Quest accepted: (.*)"])
		if text and quest:gsub(L.PART_GSUB, "") == text then
			self:DebugF(1, "Detected quest accept %q", quest)
			return self:UpdateStatusFrame()
		end

		local _, _, text = msg:find("^(.-) completed%.$")
		if type(text) == 'string' and quest:gsub(L.PART_GSUB, "") == text then
			--self:CompleteQuest(text)
			return self:UpdateStatusFrame()
		end
	end
	
	if action == "TURNIN" then
		local _, _, text = msg:find("^(.-) completed%.$")
		if type(text) == 'string' and quest:gsub(L.PART_GSUB, "") == text then
			--self:CompleteQuest(text)
			return self:UpdateStatusFrame()
		end
	end
end

--==============================================================--
--  				Add a slash command to reset the POI				 --
--==============================================================--

-- OK for 3.3.0.56
SLASH_TGJANPOI1 = '/poi'
function SlashCmdList.TGJANPOI(msg, editbox)
	if (TomTom or Cartographer_Waypoints) then
		TourGuide:PrintF("Reseting POI arrow")
		TourGuide:ResetMapCoords(false)
	end 
end

--==============================================================--
-- Add a slash command to reset the POI without using Blizard data --
--==============================================================--

-- OK for 3.3.0.56
SLASH_TGJANNOPOI1 = '/nopoi'
function SlashCmdList.TGJANNOPOI(msg, editbox)
	if (TomTom or Cartographer_Waypoints) then
		TourGuide:PrintF("Reseting POI arrow, ignoring blizard data")
		TourGuide:ResetMapCoords(true)
	end 
end

